/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.dubbo.config;

import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.status.StatusChecker;
import org.apache.dubbo.common.threadpool.ThreadPool;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.remoting.Dispatcher;
import org.apache.dubbo.remoting.Transporter;
import org.apache.dubbo.remoting.exchange.Exchanger;
import org.apache.dubbo.remoting.telnet.TelnetHandler;

import java.util.Arrays;

/**
 * The service provider default configuration
 *
 * @export
 * @see org.apache.dubbo.config.ProtocolConfig
 * @see org.apache.dubbo.config.ServiceConfig
 */
public class ProviderConfig extends AbstractServiceConfig {

  private static final long serialVersionUID = 6913423882496634749L;

  // ======== protocol default values, it'll take effect when protocol's attributes are not set ========

  /**
   * Service ip addresses (used when there are multiple network cards available)
   */
  private String host;

  /**
   * Service port
   */
  private Integer port;

  /**
   * Context path
   */
  private String contextpath;

  /**
   * Thread pool
   */
  private String threadpool;

  /**
   * Thread pool size (fixed size)
   */
  private Integer threads;

  /**
   * IO thread pool size (fixed size)
   */
  private Integer iothreads;

  /**
   * Thread pool queue length
   */
  private Integer queues;

  /**
   * Max acceptable connections
   */
  private Integer accepts;

  /**
   * Protocol codec
   */
  private String codec;

  /**
   * The serialization charset
   */
  private String charset;

  /**
   * Payload max length
   */
  private Integer payload;

  /**
   * The network io buffer size
   */
  private Integer buffer;

  /**
   * Transporter
   */
  private String transporter;

  /**
   * How information gets exchanged
   */
  private String exchanger;

  /**
   * Thread dispatching mode
   */
  private String dispatcher;

  /**
   * Networker
   */
  private String networker;

  /**
   * The server-side implementation model of the protocol
   */
  private String server;

  /**
   * The client-side implementation model of the protocol
   */
  private String client;

  /**
   * Supported telnet commands, separated with comma.
   */
  private String telnet;

  /**
   * Command line prompt
   */
  private String prompt;

  /**
   * Status check
   */
  private String status;

  /**
   * Wait time when stop
   */
  private Integer wait;

  /**
   * Whether to use the default protocol
   */
  private Boolean isDefault;

  @Deprecated
  public void setProtocol(String protocol) {
    this.protocols = Arrays.asList(new ProtocolConfig[]{new ProtocolConfig(protocol)});
  }

  @Parameter(excluded = true)
  public Boolean isDefault() {
    return isDefault;
  }

  @Deprecated
  public void setDefault(Boolean isDefault) {
    this.isDefault = isDefault;
  }

  @Parameter(excluded = true)
  public String getHost() {
    return host;
  }

  public void setHost(String host) {
    this.host = host;
  }

  @Parameter(excluded = true)
  public Integer getPort() {
    return port;
  }

  @Deprecated
  public void setPort(Integer port) {
    this.port = port;
  }

  @Deprecated
  @Parameter(excluded = true)
  public String getPath() {
    return getContextpath();
  }

  @Deprecated
  public void setPath(String path) {
    setContextpath(path);
  }

  @Parameter(excluded = true)
  public String getContextpath() {
    return contextpath;
  }

  public void setContextpath(String contextpath) {
    checkPathName("contextpath", contextpath);
    this.contextpath = contextpath;
  }

  public String getThreadpool() {
    return threadpool;
  }

  public void setThreadpool(String threadpool) {
    checkExtension(ThreadPool.class, Constants.THREADPOOL_KEY, threadpool);
    this.threadpool = threadpool;
  }

  public Integer getThreads() {
    return threads;
  }

  public void setThreads(Integer threads) {
    this.threads = threads;
  }

  public Integer getIothreads() {
    return iothreads;
  }

  public void setIothreads(Integer iothreads) {
    this.iothreads = iothreads;
  }

  public Integer getQueues() {
    return queues;
  }

  public void setQueues(Integer queues) {
    this.queues = queues;
  }

  public Integer getAccepts() {
    return accepts;
  }

  public void setAccepts(Integer accepts) {
    this.accepts = accepts;
  }

  public String getCodec() {
    return codec;
  }

  public void setCodec(String codec) {
    this.codec = codec;
  }

  public String getCharset() {
    return charset;
  }

  public void setCharset(String charset) {
    this.charset = charset;
  }

  public Integer getPayload() {
    return payload;
  }

  public void setPayload(Integer payload) {
    this.payload = payload;
  }

  public Integer getBuffer() {
    return buffer;
  }

  public void setBuffer(Integer buffer) {
    this.buffer = buffer;
  }

  public String getServer() {
    return server;
  }

  public void setServer(String server) {
    this.server = server;
  }

  public String getClient() {
    return client;
  }

  public void setClient(String client) {
    this.client = client;
  }

  public String getTelnet() {
    return telnet;
  }

  public void setTelnet(String telnet) {
    checkMultiExtension(TelnetHandler.class, Constants.TELNET, telnet);
    this.telnet = telnet;
  }

  @Parameter(escaped = true)
  public String getPrompt() {
    return prompt;
  }

  public void setPrompt(String prompt) {
    this.prompt = prompt;
  }

  public String getStatus() {
    return status;
  }

  public void setStatus(String status) {
    checkMultiExtension(StatusChecker.class, "status", status);
    this.status = status;
  }

  @Override
  public String getCluster() {
    return super.getCluster();
  }

  @Override
  public Integer getConnections() {
    return super.getConnections();
  }

  @Override
  public Integer getTimeout() {
    return super.getTimeout();
  }

  @Override
  public Integer getRetries() {
    return super.getRetries();
  }

  @Override
  public String getLoadbalance() {
    return super.getLoadbalance();
  }

  @Override
  public Boolean isAsync() {
    return super.isAsync();
  }

  @Override
  public Integer getActives() {
    return super.getActives();
  }

  public String getTransporter() {
    return transporter;
  }

  public void setTransporter(String transporter) {
    checkExtension(Transporter.class, Constants.TRANSPORTER_KEY, transporter);
    this.transporter = transporter;
  }

  public String getExchanger() {
    return exchanger;
  }

  public void setExchanger(String exchanger) {
    checkExtension(Exchanger.class, Constants.EXCHANGER_KEY, exchanger);
    this.exchanger = exchanger;
  }

  /**
   * typo, switch to use {@link #getDispatcher()}
   *
   * @deprecated {@link #getDispatcher()}
   */
  @Deprecated
  @Parameter(excluded = true)
  public String getDispather() {
    return getDispatcher();
  }

  /**
   * typo, switch to use {@link #getDispatcher()}
   *
   * @deprecated {@link #setDispatcher(String)}
   */
  @Deprecated
  public void setDispather(String dispather) {
    setDispatcher(dispather);
  }

  public String getDispatcher() {
    return dispatcher;
  }

  public void setDispatcher(String dispatcher) {
    checkExtension(Dispatcher.class, Constants.DISPATCHER_KEY, dispatcher);
    checkExtension(Dispatcher.class, "dispather", dispatcher);
    this.dispatcher = dispatcher;
  }

  public String getNetworker() {
    return networker;
  }

  public void setNetworker(String networker) {
    this.networker = networker;
  }

  public Integer getWait() {
    return wait;
  }

  public void setWait(Integer wait) {
    this.wait = wait;
  }

}
